﻿using AutoMapper;
using CK.Sprite.Cache;
using CK.Sprite.Framework;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using MySqlX.XDevAPI.Common;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace CK.Sprite.Form.Core
{
    public abstract class DbBaseFrameworkCache<T> : IFrameworkCache<T>
    {
        protected IServiceProvider _serviceProvider => ServiceLocator.ServiceProvider;
        protected readonly object ServiceProviderLock = new object();
        protected TService LazyGetRequiredService<TService>(ref TService reference)
            => LazyGetRequiredService(typeof(TService), ref reference);

        protected TRef LazyGetRequiredService<TRef>(Type serviceType, ref TRef reference)
        {
            if (reference == null)
            {
                lock (ServiceProviderLock)
                {
                    if (reference == null)
                    {
                        reference = (TRef)_serviceProvider.GetRequiredService(serviceType);
                    }
                }
            }

            return reference;
        }

        public IMapper Mapper => LazyGetRequiredService(ref _mapper);
        private IMapper _mapper;

        protected DefaultDbConfig DefaultDbConfig => LazyGetRequiredService(ref _defaultDbConfig).Value;
        private IOptions<DefaultDbConfig> _defaultDbConfig;

        public abstract string CacheKey { get; }

        public virtual string GetCurrentCacheVersion()
        {
            if (!LocalCacheContainer.IsEnabledLocalCache)
            {
                return _serviceProvider.DoDapperService(DefaultDbConfig, (unitOfWork) =>
                {
                    var spriteCacheMainRepository = new RepositoryBase<SpriteCacheMain, string>(unitOfWork);
                    return spriteCacheMainRepository.Get(CacheKey)?.Version;
                });
            }
            else
            {
                return (string)LocalCacheContainer.Get($"{CommonConsts.SpriteFormCachePreKey}-CacheMain_{CacheKey}", key =>
                {
                    return _serviceProvider.DoDapperService(DefaultDbConfig, (unitOfWork) =>
                    {
                        var spriteCacheMainRepository = new RepositoryBase<SpriteCacheMain, string>(unitOfWork);
                        return spriteCacheMainRepository.Get(CacheKey)?.Version;
                    });
                });
            }
        }

        public virtual List<T> GetBusinessCacheDtos()
        {
            return null;
        }
    }
}
